home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr11
/
ddj9304.zip
/
WAVELET.ZIP
/
V592X480.C
< prev
next >
Wrap
Text File
|
1992-05-17
|
13KB
|
456 lines
/* V592X480.C */
/* Mode set routine for VGA 592x480 16-color mode.
Tested with Borland C 2.0 */
#include <stdlib.h>
#include <dos.h>
#include "V592x480.h"
unsigned ROMsetSEG, ROMsetOFF;
unsigned far *ROMset;
unsigned char far *ROMptr;
unsigned char palette_set[17] = {0, 1, 60, 3, 4, 5, 6, 55,
1, 62, 1, 62, 56, 62, 7, 62, 0};
void Set592x480(void)
{
union REGS regset;
struct SREGS sregset;
/* First, set to standard 640x480 mode (mode 12h) */
regset.x.ax = 0x0012;
int86(0x10, ®set, ®set);
/* Obtain location of 8x8 pixel character set */
ROMset = (unsigned far *) MK_FP(0x0, 0x10c);
regset.x.ax = 0x1123;
regset.h.bl = 0x03;
int86(0x10, ®set, ®set);
ROMsetOFF = ROMset[0];
ROMsetSEG = ROMset[1];
ROMptr = (unsigned char far *) MK_FP(ROMsetSEG, ROMsetOFF);
/* Next, set up the new color palette */
regset.x.ax = 0x1002;
regset.x.dx = (unsigned int) palette_set;
sregset.es = _DS;
int86x(0x10, ®set, ®set, &sregset);
/* Now, tweak the registers needed to convert the horizontal character
count from 80 to 74 characters (640 to 592 pixels) per line */
outportb(0x3D4, 0x11); /* allow access to CRTC registers 0 - 7 */
outportb(0x3D5, inportb(0x3D5) & 0x7f);
outport(0x3D4, 0x4901); /* adjust the Horizontal Display Enable End
register for 74 byte display area width */
outport(0x3D4, 0x2513); /* adjust the Offset register for 74 byte
(37 word) display area width */
/* adjust the Line Compare register to start display of
non-flipping area at line 400 (row scan number 399 (0x18f) */
outportb(0x3D4, 9); /* clear tenth bit of Line Compare count */
outportb(0x3D5, inportb(0x3D5) & 0xbf);
outportb(0x3D4, 7); /* set ninth bit of Line Compare count */
outportb(0x3D5, inportb(0x3D5) | 0x10);
outport(0x3D4, 0x8f18); /* remaining eight bits of Line Compare */
/* adjust the Start Address High and Start Address Low registers
to start screen display on page 0 */
outport(0x3D4, 0x170c);
outport(0x3D4, 0x200d);
outportb(0x3D4, 0x11); /* block access to CRTC registers 0 - 7 */
outportb(0x3D5, inportb(0x3D5) | 0x80);
}
void DrawObject(int page, int A[][5])
{
int i;
/* draw each rectangle in list until 'null' rectangle is encountered */
for(i = 0; A[i][0] >= 0; i++)
ColorRectangle(page, A[i][0], A[i][1], A[i][2], A[i][3], A[i][4]);
}
void DrawGraph(int left, int top, int right, int bot,double *data,
double magnitude, int length, int color, int barsize)
{
double range, scale;
int i, j, index, width, center, offset, last_offset, Ltop, Lbot;
j = barsize - 1;
width = right - left - 1;
center = (bot + top) / 2;
range = 0.95 * (double) ((bot - top - 1) / 2);
scale = range / magnitude;
/* limit length of data to fit within bounds of the graph */
if ((length * barsize) > width)
length = width / barsize;
last_offset = 0;
for(i = 0, index = left + 1; i < length; index += barsize, i++)
{ /* draw the bars of the graph */
offset = (int) (data[i] * scale);
if (offset > last_offset) /* properly format excursion in Y direction */
{
Ltop = center - offset;
Lbot = center - last_offset;
}
else if (offset < last_offset)
{
Ltop = center - last_offset;
Lbot = center - offset;
}
else
{
Ltop = center - offset;
Lbot = center - offset;
}
ColorRectangle(STATIC_PAGE, index, Ltop, index + j, Lbot, color);
last_offset = offset;
}
}
#define CLD 0xfc
#define PUSH_DS 0x1e
#define PUSH_CX 0x51
#define POP_DS 0x1f
#define POP_CX 0x59
#define REP 0xf3
#define MOVSB 0xa4
#define STOSB 0xaa
#define INSW 0x6d
#define DEC_AX 0X48
#define DEC_BX 0x4b
#define DEC_CX 0X49
#define DEC_DX 0X4a
#define INC_DX 0X42
#define DEC_SI 0X4e
#define JNE 0X75
#define OUTSB 0x6e
#define OUT_DX_AL 0xee
#define USE_ES 0x26
#define MOV_AL_DI 0x058a
#define MOV_CX_AX 0xc88b
#define MOV_CX_DX 0xca8b
#define MOV_DI_CL 0x0d88
#define ADD_DI_BX 0xfb03
#define ADD_SI_BX 0xf303
#define ADD_SI_CX 0xf103
#define SUB_SI_CX 0xf12b
int DrawChar(int page, int row, int col, int color, int c)
{
int maxrow;
unsigned page_base;
/* determine location of page on which to draw the character */
switch (page)
{
case PAGE_0:
page_base = 0x1720;
maxrow = 400;
break;
case PAGE_1:
page_base = 0x8b20;
maxrow = 400;
break;
case STATIC_PAGE:
page_base = 0x0;
maxrow = 80;
}
/* abort attempt to draw outside page boundaries */
if ((row >= maxrow) || (col >= 74))
return -1;
/* set the Mode Register Write Mode to 2 */
outportb(0x3ce, 5); outportb(0x3cf, (inportb(0x3cf) & 0xfc) | 0x02);
/* point to the Bit Mask Register */
outportb(0x3ce, 8);
_DI = page_base + (row * 74) + col;
_SI = ROMsetOFF + (c << 3);
_ES = 0xa000;
_CL = color;
_BX = 8;
_DX = 0x03cf; /* set up port address for Bit Mask Register */
__emit__(PUSH_DS);
_DS = ROMsetSEG;
__emit__(OUTSB, USE_ES, MOV_AL_DI, USE_ES, MOV_DI_CL);
_DI += 74;
__emit__(DEC_BX, JNE, 0xef, POP_DS);
/* enable all bits in Bit Mask Register */
outportb(0x3cf, 0xff);
/* set the Mode Register Write Mode to 0 */
outportb(0x3ce, 5); outportb(0x3cf, inportb(0x3cf) & 0xfc);
return(c);
}
int DrawString(int page, int row, int col, int color, char *c)
{
int maxrow, j;
unsigned page_base;
char ch;
/* set the Mode Register Write Mode to 2 */
outportb(0x3ce, 5); outportb(0x3cf, (inportb(0x3cf) & 0xfc) | 0x02);
/* point to the Bit Mask Register */
outportb(0x3ce, 8);
/* determine location of page on which to draw the character */
switch(page)
{
case PAGE_0:
page_base = 0x1720;
maxrow = 400;
break;
case PAGE_1:
page_base = 0x8b20;
maxrow = 400;
break;
case STATIC_PAGE:
page_base = 0x0;
maxrow = 80;
}
/* abort attempt to draw outside page boundary */
if (row >= maxrow)
return -1;
_ES = 0xa000;
_DI = page_base + (row * 74) + col;
_CL = color;
j = 0;
while ((ch = c[j++]) != '\0')
{
_SI = ROMsetOFF + (ch << 3);
_BX = 8;
_DX = 0x03cf; /* set up port address for Bit Mask Register */
__emit__(PUSH_DS);
_DS = ROMsetSEG;
__emit__(OUTSB, USE_ES, MOV_AL_DI, USE_ES, MOV_DI_CL);
_DI += 74;
__emit__(DEC_BX, JNE, 0xef, POP_DS);
_DI -= 591;
}
/* enable all bits in Bit Mask Register */
outportb(0x3cf, 0xff);
/* set the Mode Register Write Mode to 0 */
outportb(0x3ce, 5); outportb(0x3cf, inportb(0x3cf) & 0xfc);
return(0);
}
unsigned char colorarray[74];
unsigned char leftedges[8] = {0xff, 0x7f, 0x3f, 0x1f,
0x0f, 0x07, 0x03, 0x01};
unsigned char rightedges[8] = { 0x80, 0xc0, 0xe0, 0xf0,
0xf8, 0xfc, 0xfe, 0xff };
void ColorRectangle(int page, int left, int top, int right, int bot, int color)
{
int i, temp, vmax;
int leftedgebyte, rightedgebyte;
unsigned int leftedgesize, rightedgesize;
unsigned int byteblocksize, wrapblocksize;
unsigned char leftedgeblock, rightedgeblock;
/* limit horizontal range to page size */
left = max(0, left); left = min(591, left);
right = max(0, right); right = min(591, right);
/* correct accending order of horizontal coordinates */
if (right < left)
{
temp = left; left = right; right = temp;
}
if (page == STATIC_PAGE) /* static page does not filp - size is 591 x 80 */
vmax = 79;
else
vmax = 399; /* pages 0 and 1 filp - size is 591 x 400 */
/* limit vertical range to page size */
top = max(0, top); top = min(vmax, top);
bot = max(0, bot); bot = min(vmax, bot);
/* correct accending order of vertical coordinates */
if (bot < top)
{
temp = top; top = bot; bot = temp;
}
/* calculate byte position of left and right edges */
leftedgebyte = left / 8; rightedgebyte = right / 8;
/* calculate bit position of left and right edges */
leftedgesize = left - leftedgebyte * 8;
rightedgesize = right - rightedgebyte * 8;
/* calculate integral byte width of rectangle and
wrap around index for drawing routine */
byteblocksize = rightedgebyte - leftedgebyte + 1;
wrapblocksize = 74 - byteblocksize;
/* get pixel maps of left and right edges */
leftedgeblock = leftedges[leftedgesize];
rightedgeblock = rightedges[rightedgesize];
/* combine pixel maps if left and right edges are on the same byte */
if (leftedgebyte == rightedgebyte)
leftedgeblock &= rightedgeblock;
/* set up color for the rectangle */
for (i = 0; i < byteblocksize; i++)
colorarray[i] = color;
/* set the Mode Register Write Mode to 2 */
outportb(0x3ce, 5); outportb(0x3cf, (inportb(0x3cf) & 0xfc) | 0x02);
/* point to the Bit Mask Register */
outportb(0x3ce, 8);
__emit__(CLD); /* assure that MOVSB increments SI and DI */
if (page == 0) /* set up starting address of selected page */
_DI = 0x1720;
else if (page == 1)
_DI = 0x8b20;
else
_DI = 0x0000;
/* adjust start to upper lefthand corner of the rectangle */
_DI += leftedgebyte + top * 74;
_ES = 0xa000; /* set segment for screen memory */
_DX = 0x03cf; /* set up port address for Bit Mask Register */
for (i = 0; i < bot - top + 1; i++)
{
_SI = (unsigned int) colorarray;
_AL = leftedgeblock;
/* current pixels in byte of left edge need to be preserved
by reading the memory location location first */
__emit__(OUT_DX_AL, USE_ES, MOV_AL_DI, MOVSB);
if (byteblocksize > 1) /* more than one byte wide */
{
if (byteblocksize > 2) /* more than two bytes wide */
{
_CX = byteblocksize - 2;
/* all pixels in byte are over-written in body of rectangle,
so no pixels need to be preserved; speeds up drawing! */
_AL = 0xff;
__emit__(OUT_DX_AL, REP, MOVSB);
}
_AL = rightedgeblock;
/* current pixels in byte of right edge need to be preserved
by reading the memory location location first */
__emit__(OUT_DX_AL, USE_ES, MOV_AL_DI, MOVSB);
}
_DI += wrapblocksize;
}
/* enable all bits in Bit Mask Register */
outportb(0x3cf, 0xff);
/* set the Mode Register Write Mode to 0 */
outportb(0x3ce, 5); outportb(0x3cf, inportb(0x3cf) & 0xfc);
}
static unsigned int shift_blocks[7][2]
= { {42, 32}, {26, 48}, {18, 56},
{14, 60}, {12, 62}, {11, 63}, {11, 63}};
void ShiftWaveTraces(unsigned int src, unsigned int dest)
{
int i;
/* set the Mode Register Write Mode to 1 */
outportb(0x3ce, 5);
outportb(0x3cf, (inportb(0x3cf) & 0xfc) | 0x01);
/* set the Map Mask Register to enable writes to pixel planes
0, 1, and 3 and disable writes to pixel plane 2 */
outport(0x3c4, 0x0b02);
_SI = src;
_DI = dest + 10;
_ES = 0xa000;
__emit__(CLD); /* assure that MOVSB increments SI and DI */
for (i = 0; i < 7; i++)
{
_DX = shift_blocks[i][1]; /* load the length of each line for block */
_BX = shift_blocks[i][0]; /* init middle loop for wrap value for block */
__emit__(PUSH_DS);
_DS = 0xa000;
_AX = 50; /* init middle loop for number of lines in block */
__emit__(ADD_SI_BX, MOV_CX_DX, REP, MOVSB);
__emit__(ADD_DI_BX, DEC_AX, JNE, 0xf5, POP_DS);
}
/* set the Mode Register Write Mode to 0 */
outportb(0x3ce, 5);
outportb(0x3cf, inportb(0x3cf) & 0xfc);
/* set the Map Mask Register to enable writes to all pixel planes */
outport(0x3c4, 0x0f02);
}
static unsigned int imag_blocks[6][2]
= { {10, 32}, {42, 16}, {58, 8}, {66, 4}, {70, 2}, {72, 1} };
void GetDSPimage(unsigned int dest, unsigned io_addr)
{
int i;
/* Map Mask register - set pixel planes 1, 2, and 3 to "0",
pixel plane 0 to "1" */
outport(0x3c4, 0x0102);
_DX = io_addr;
_DI = dest;
_ES = 0xa000;
__emit__(CLD); /* assure that INSW increments DI */
for (i = 0; i < 6; i++)
{
/* point to fill element offset */
_AX = imag_blocks[i][1]; /* load the length of each line for block */
_BX = imag_blocks[i][0]; /* init middle loop for wrap value for block */
_SI = 50; /* init middle loop for number of lines in image block */
__emit__(ADD_DI_BX); /* wrap destination pointer to next row of display */
__emit__(MOV_CX_AX, REP, INSW, DEC_SI, JNE, 0xf7);
}
_DI += 1; /* offset pointer by one */
_CX = imag_blocks[5][0]; /* init middle loop for wrap value for block */
_SI = 100; /* init middle loop for number of lines in image block */
__emit__(ADD_DI_BX, INSW, DEC_SI, JNE, 0xfa);
/* Map Mask register - set pixel planes 0 - 3 to "1" */
outport(0x3c4, 0x0f02);
}